﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace PartitionsCodegen
{
    class CNCCode
    {
        private CNCFigure[,] copies;
        private int ncopies;
        private float[] depths;
        private decimal offset_x;
        private decimal offset_y;
        private string s_code;
        private bool to_the_right;
        private decimal size;

        //CNC code generator
        public CNCCode(string s_code, int ncopies, float[] depths, decimal offset_x, decimal offset_y, bool to_the_right)
        {
            this.s_code = s_code;
            this.ncopies = ncopies;
            this.depths = depths;
            this.offset_x = offset_x;
            this.offset_y = offset_y;
            this.to_the_right = to_the_right;

            int n_depths = depths.Length;

            this.copies = new CNCFigure[ncopies , n_depths];
            CNCFigure original = new CNCFigure(s_code, offset_x, offset_y,depths[0]);
            this.copies[0, 0] = original;
            Console.WriteLine(original.getString());

            size = calculate_size();
            Console.WriteLine("Size=" + size);

            int limit = to_the_right ? Program.getBoardLimitX() : Program.getBoardLimitY();
            if ((size * ncopies) > limit)
            {   string dim =  to_the_right ? "ancho " : "alto ";
                string msj = "Advertencia: El corte exige "+(size*ncopies) +" ("+ncopies+" copias de "+dim+size+" cada una)\n"+
                    "lo que el limite de " +dim+" de plancha establecido de "+limit;

                Program.errorAlert(msj);
            
            }

            for (int i = 0; i < ncopies; i++)
            {
                for (int j = 0; j < n_depths; j++)
                {
                    this.copies[i,j] = new CNCFigure(original, i, size, depths[j], to_the_right);
                }
            }
        }

        private decimal getStartingX(int i, int z)
        {
            //if (to_the_right) return offset_x + (size * i);
            //else return offset_x;
            return this.copies[i, z].getStartingX();
        }
        private decimal getStartingY(int i, int z)
        {
            //if (to_the_right) return offset_y;
            //else return offset_y + (size * i);
            return this.copies[i, z].getStartingY();
            
        }

        //CNC Code to String
        public string getString(){
            int n_depths = depths.Length;
            int ncopiesTotal = this.ncopies * n_depths;
            string[] codeAll = new string[ncopiesTotal];

            string output = "";

           
            for (int i = 0; i < this.ncopies; i++)
            {
                output += "(Copia " + (i+1) + " - Inicio - )\r\n";
                output += "G00 X" + getStartingX(i,0) + " Y" + getStartingY(i,0) + " Z" + Program.getZForLifts() + "\r\n";
                
                for (int z = 0; z < n_depths; z++)
                {
                    output += "(Copia " + (i + 1) + ", Profundidad " + (z+1) + ": z=" + depths[z] + ")\r\n";
                    output += copies[i, z].getString()+"\r\n";

                    if (Program.getLiftBetweenZs() && z<(n_depths-1))
                    {
                        output += "G01 Z" + Program.getZForLifts()+"\r\n";
                        if (Program.getDwellTimeZ() > 0)
                            output += "G04 P" + Program.getDwellTimeZ()+"\r\n";

                        output += "G00 X" + getStartingX(i,z+1) + " Y" +getStartingY(i,z+1) + "\r\n";
                    }


                }

                output += "G01 Z" + Program.getZForLifts() + "\r\n";
                if (Program.getDwellTimeCopies() > 0)
                    output += "G04 P" + Program.getDwellTimeCopies() + "\r\n";

            }
            return output;
        }

        private decimal calculate_size()
        {
            if (to_the_right) return copies[0, 0].calculate_size_X();
            else return copies[0, 0].calculate_size_Y();
        }
    }
}
